package util;

import java.util.HashMap;
import java.util.Map;

/**
 * 存储当前登录用户的类<br>
 * 
 * 
 * CurrentUserHolder
 * 
 * DingZhanhe 2013-1-6 下午5:28:50
 * 
 * @version 1.0.0
 * 
 */
public class CurrentUserHolder {

  /** 登录日志ID */
  public static final String LOGIN_LOG_ID = "loginLogId";
  /** 当前登录用户ID */
  public static final String CURRENT_USER_ID = "CurrentUserId";
  /** Thread局部变量 */
  private static final ThreadLocal<Map<String, Object>> threadSession = new ThreadLocal<Map<String, Object>>();

  /**
   * 此方法可以在登录后的任意处调用，均可获取到当前登录者ID，而不用从上下文中传递
   * 
   * @return
   * @throws Exception
   *         Long
   * @exception
   * @since 1.0.0
   */
  public static Long getCurrentUserId() throws Exception {
    Long curUserId = (Long) getThreadLocalMap().get(CURRENT_USER_ID);
    if (curUserId == null) {
      String msg = "当前用户已退出登录,无法获取到当前登录用户信息。";
      LoggerUtils.errorInfo(msg);
      throw new Exception(msg);
    }
    return curUserId;
  }

  /**
   * Thread局部变量中获取登录日志ID
   * 
   * @return Long
   * @throws Exception
   * @exception
   * @since 1.0.0
   */
  public static Long getLoginLogId() throws Exception {
    Long loginLogId = (Long) getThreadLocalMap().get(LOGIN_LOG_ID);
    if (loginLogId == null) {
      String msg = "当前用户已退出登录,无法获取到当前登录用户登录日志ID。";
      LoggerUtils.errorInfo(msg);
      // throw new Exception(msg);如果获取不了则不用抛出异常，也可以用户ID进行查询记录
    }
    return loginLogId;
  }

  /**
   * 获取Thread局部变量Map
   * 
   * @return Map<String,Object>
   * @exception
   * @since 1.0.0
   */
  private static Map<String, Object> getThreadLocalMap() {
    Map<String, Object> map = threadSession.get();
    if (map == null) {
      map = new HashMap<String, Object>();
    }
    return map;
  }

  /**
   * 此方法一般应在filter中被调用,依赖于当前已登录。
   * 
   * @param curUserId
   * @throws Exception
   * @exception
   * @since 1.0.0
   */
  public static void set(Long curUserId) throws Exception {
    Map<String, Object> map = getThreadLocalMap();
    map.put(CURRENT_USER_ID, curUserId);
    threadSession.set(map);
  }

  /**
   * Thread局部变量中添加登录日志ID
   * 
   * @param loginLogId
   * @throws Exception
   * @exception
   * @since 1.0.0
   */
  public static void setLoginLogId(Long loginLogId) throws Exception {
    Map<String, Object> map = getThreadLocalMap();
    map.put(LOGIN_LOG_ID, loginLogId);
    threadSession.set(map);
  }
}
